import React, { useEffect, useMemo, useReducer, useRef, useState } from 'react';
import SpecialFolder from '@/ts/core/thing/folder';
import { useRefInit } from '@/hooks/useRefInit';
import { IBelong, IDirectory, ISysFileInfo, ITarget } from '@/ts/core';
import cls from './index.module.less';

import { Button, Empty, Input, Space, Tag } from 'antd';
import ListMode from '@/components/Directory/views/listMode';
import { WithPath } from '@/ts/core/thing/folder';
import FullScreenModal from '@/components/Common/fullScreen';
import FileView from './FileView';
import { GroupNames, groupList } from '@/ts/core/thing/folder/FileFilter';
import { executeCmd, uploadFile } from '@/executor/action';
import { command } from '@/ts/base';
import { useSessionContext } from '../content';
import { useLocation } from 'react-router-dom';

interface Props {
  target: ITarget;
}

interface Payload {
  type: 'add' | 'clear';
  files: WithPath<ISysFileInfo>[];
}
const DirectoryView = (props: Props) => {
  const { updateContent } = useSessionContext();

  const folder = useRef<SpecialFolder>(null!);

  const [prevDir, setPrevDir] = useState<IDirectory | undefined>(undefined);

  const [refreshKey, refresh] = useReducer((state: boolean) => !state, false);

  const [files, setFiles] = useReducer(
    (state: WithPath<ISysFileInfo>[], payload: Payload) => {
      if (payload.type === 'clear') {
        return [];
      }
      return [...state, ...payload.files];
    },
    [],
  );
  const [finished, setFinished] = useState(false);
  const [nextDir, setNextDir] = useState<IDirectory | null>(null);

  const [currentFile, setCurrentFile] = useState<WithPath<ISysFileInfo> | undefined>(
    undefined,
  );
  const [previewFiles, setPreviewFiles] = useState<WithPath<ISysFileInfo>[]>([]);
  const [previewVisible, setPreviewVisible] = useState(false);

  const [searchText, setSearchText] = useState('');
  const [groupName, setGroupName] = useState<GroupNames | ''>('');
  const filtered = useMemo(() => {
    return folder.current?.applyFilter(groupName, searchText) ?? [];
  }, [searchText, groupName, files]);
  const [visible, setVisible] = useState<boolean>(false); // 控制是否显示
  const location = useLocation(); // 获取当前路由信息

  useEffect(() => {
    if (location.pathname === '/home') {
      setVisible(true);
    }
    let f = init(props.target.directory, props.target.directory == prevDir);
    setPrevDir(props.target.directory);
    return f;
  }, [props.target.directory, refreshKey]);

  function init(directory: IDirectory, reload = false) {
    const ctl = new AbortController();

    folder.current = new SpecialFolder(directory);
    folder.current.startLoadFiles(
      {
        onFoundFiles: (f, finished) => {
          if (!finished) {
            setFiles({
              type: 'add',
              files: f,
            });
          } else {
            setFinished(true);
            setNextDir(null);
          }
        },
        onNextDirectory(directory) {
          setNextDir(directory);
        },
        onError: (error) => {
          if (error.message !== 'DESTROY') {
            console.error(error);
          }
        },
        cancelToken: ctl.signal,
      },
      reload,
    );

    return () => {
      ctl.abort('DESTROY');
      setFiles({ type: 'clear', files: [] });
      setFinished(false);
      setNextDir(null);
      folder.current = null!;
    };
  }

  function fileOpen(file: ISysFileInfo) {
    setCurrentFile(file);
    setPreviewFiles(files);
    setPreviewVisible(true);
  }

  return (
    <div className={cls['root']}>
      <div className={cls['left']} style={{ width: '100%' }}>
        <div className={cls['header']}>
          <span className={cls['title']}>{props.target.name} 数据</span>
        </div>
        <div className={cls['header']}>
          <Space>
            {groupList.map((g) => {
              return (
                <Tag
                  key={g.name}
                  className={[
                    cls['file-type-tag'],
                    g.name == groupName ? cls['is-selected'] : '',
                  ].join(' ')}
                  onClick={() => setGroupName(g.name)}>
                  {g.label}
                </Tag>
              );
            })}
          </Space>

          <div style={{ flex: 1 }}></div>
          <Space>
            {visible && (
              <Button
                onClick={() => {
                  updateContent('bench');
                }}>
                返回工作台
              </Button>
            )}
            <Button
              onClick={() => {
                uploadFile(props.target.directory as any, (f) => {
                  setFiles({
                    type: 'add',
                    files: [f as any],
                  });
                });
              }}>
              上传
            </Button>
            <Button
              onClick={() => {
                command.emitter('executor', 'taskList', props.target.directory);
              }}>
              上传列表
            </Button>
            <Button
              onClick={() => {
                refresh();
              }}>
              刷新
            </Button>
            <div style={{ width: ' 300px' }}>
              <Input
                placeholder="搜索文件"
                value={searchText}
                onChange={(e) => setSearchText(e.target.value)}
                allowClear
              />
            </div>
          </Space>
        </div>
        <div className={cls['file-list']}>
          <ListMode
            selectFiles={[]}
            focusFile={currentFile}
            content={filtered}
            fileOpen={(file, _) => fileOpen(file as ISysFileInfo)}
            contextMenu={() => ({ items: [] })}
          />
        </div>
        <div className={cls['footer']}>
          <span>{finished ? '加载完成' : '正在查找 ' + (nextDir?.name ?? '')}</span>
        </div>
      </div>
      {previewVisible && (
        <FullScreenModal
          open
          centered
          fullScreen
          bodyHeight={'80vh'}
          destroyOnClose
          title="文件预览"
          onCancel={() => setPreviewVisible(false)}>
          <FileView files={previewFiles} initFile={currentFile} fileType={groupName} />
        </FullScreenModal>
      )}
    </div>
  );
};

export default DirectoryView;
